'''
copyright: Copyright (C) 2015-2024, Wazuh Inc.

           Created by Wazuh, Inc. <info@wazuh.com>.

           This program is free software; you can redistribute it and/or modify it under the terms of GPLv2

type: integration

brief: Wazuh is able to detect vulnerabilities in the applications installed in agents using the Vulnerability Detector
       module. This software audit is performed through the integration of vulnerability feeds indexed by Redhat,
       Canonical, Debian, Amazon Linux and NVD Database.

components:
    - vulnerability_detector

suite: providers

targets:
    - manager

daemons:
    - wazuh-modulesd
    - wazuh-db
    - wazuh-analysisd

os_platform:
    - linux

os_version:
    - Arch Linux
    - Amazon Linux 2
    - Amazon Linux 1
    - CentOS 8
    - CentOS 7
    - Debian Buster
    - Red Hat 8
    - Ubuntu Focal
    - Ubuntu Bionic
    - Ubuntu Xenial
    - Ubuntu Trusty
    - Ubuntu Jammy
    - SUSE Linux Enterprise Desktop 11
    - SUSE Linux Enterprise Desktop 12
    - SUSE Linux Enterprise Desktop 15
    - SUSE Linux Enterprise Server 11
    - SUSE Linux Enterprise Server 12
    - SUSE Linux Enterprise Server 15

references:
    - https://documentation.wazuh.com/current/user-manual/capabilities/vulnerability-detection/index.html
    - https://documentation.wazuh.com/current/user-manual/reference/ossec-conf/vuln-detector.html#provider

tags:
    - settings
    - vulnerability
    - vulnerability_detector
    - providers
'''
import pytest
from pathlib import Path
from datetime import date

from wazuh_testing.constants.paths.logs import WAZUH_LOG_PATH
from wazuh_testing.utils.callbacks import generate_callback
from wazuh_testing.tools.monitors.file_monitor import FileMonitor
from wazuh_testing.utils.db_queries import cve_db
from wazuh_testing.utils.services import control_service
from wazuh_testing.utils.configuration import get_test_cases_data, load_configuration_template
from wazuh_testing.modules.modulesd.vulnerability_detector import patterns as cb
from wazuh_testing.modules.modulesd.configuration import MODULESD_DEBUG
from wazuh_testing.modules.monitord.configuration import MONITORD_ROTATE_LOG
from wazuh_testing.modules.modulesd.patterns import CONFIGURATION_ERROR
from . import TEST_CASES_PATH, CONFIGURATIONS_PATH


pytest.skip("The tests will be deprecated, they test the old Vulnerability Detector.", allow_module_level=True)

# Variables
local_internal_options = {MODULESD_DEBUG: '2', MONITORD_ROTATE_LOG: '0'}
pytestmark = [pytest.mark.server]

# Configuration and cases data
configurations_path = Path(CONFIGURATIONS_PATH, 'configuration_missing_os.yaml')
cases_path = Path(TEST_CASES_PATH, 'cases_missing_os.yaml')

# Test configurations
configuration_parameters, configuration_metadata, test_case_ids = get_test_cases_data(cases_path)
configurations = load_configuration_template(configurations_path, configuration_parameters,
                                             configuration_metadata)

# Add <update_from_year> tag for NVD to download only the last year feed and speed up the testing process
for index in range(len(configurations)):
    if configurations[index]['sections'][0]['elements'][1]['provider']['attributes'][0]['name'] == 'nvd':
        configurations[index]['sections'][0]['elements'][1]['provider']['elements'].append(
            {'update_from_year': {'value': date.today().year}})


@pytest.mark.tier(level=0)
@pytest.mark.parametrize('test_configuration, test_metadata', zip(configurations, configuration_metadata),
                         ids=test_case_ids)
def test_providers_missing_os(test_configuration, test_metadata, set_wazuh_configuration, truncate_monitored_files,
                              configure_local_internal_options, restart_wazuh_daemon_after_finishing_module):
    '''
    description: Check if modulesd starts downloading the feeds without specifying the os version. To do this, it checks
                 if errors occur when the <os> tag is omitted in the configuration in providers that should have it and,
                 on the other hand, if the update of the feeds starts normally in providers that do not require this
                 tag.

    test_phases:
        - setup:
            - Set a custom Wazuh configuration without <os> tag on the provider.
            - Configure custom local_internal_options.
            - Truncate wazuh logs.
        - test:
            - Check the update starts on OSs where <os> tag is not required
            - Check the error message appears on OSs where <os> tag is required
        - teardown:
            - Truncate wazuh logs.
            - Restore initial configuration,and local_internal_options.
            - Restart modulesd to apply configuration.

    wazuh_min_version: 4.4.0

    tier: 0

    parameters:
      - test_configuration:
            type: dict
            brief: Wazuh configuration data. Needed for set_wazuh_configuration fixture.
        - test_metadata:
            type: dict
            brief: Wazuh configuration metadata
        - set_wazuh_configuration:
            type: fixture
            brief: Set the wazuh configuration according to the configuration data.
        - truncate_monitored_files:
            type: fixture
            brief: Truncate all the log files and json alerts files before and after the test execution.
        - configure_local_internal_options:
            type: fixture
            brief: Set local_internal_options configuration.
        - restart_wazuh_daemon_after_finishing_module:
            type: fixture
            brief: Restart wazuh modules after finishing the test module.

    assertions:
        - The provider os data update starts when `os` has not a determined value.
        - The error message appears when `os` tag is not present in Amazon Linux, Canonical and Debian providers.

    input_description:
        - The `test_no_os.yaml` file provides the module configuration for this test.

    expected_output:
        - r'.*: Configuration error at.*'
        - 'Starting <provider_name>  database update'
    '''
    provider_name = test_metadata['provider_name']
    file_monitor = FileMonitor(WAZUH_LOG_PATH)

    try:
        control_service('restart')
    except ValueError:
        # These providers that aren't expected to work without the <os> tag.
        file_monitor.start(callback=generate_callback(regex=CONFIGURATION_ERROR))
        assert file_monitor.callback_result is not None, f"Expected '{CONFIGURATION_ERROR}' event was not found."
    else:
        operating_system = test_metadata['os'][0]
        if operating_system != '':
            os_name = f"{provider_name} {operating_system}"
        else:
            os_name = f"JSON {provider_name}" if 'Red Hat' in provider_name else f"{provider_name}"
        # Check update starts on providers that work without n <os> tag.
        callback = generate_callback(regex=cb.DATABASE_UPDATE_STARTING,
                                     replacement={"provider_name": os_name})
        file_monitor.start(timeout=180, callback=callback)
        assert file_monitor.callback_result is not None, f"Unexpected '{cb.DATABASE_UPDATE_STARTING}' event was found."
